import { Component, OnInit, OnDestroy, Inject } from '@angular/core'
import { DOCUMENT } from '@angular/common'
import { ActivatedRoute } from '@angular/router'
import { NzMessageService } from 'ng-zorro-antd'
import { PageScrollService } from 'ngx-page-scroll-core'
import { ACLService } from '@delon/acl'

import { Store, StoreUpdate, IStoreQueryParams } from '@shared/interfaces/store'
import { PageService } from '@shared/services/page.service'
import { StoreService } from '../store.service'
import { DataService } from '@shared/services/data.service'
import { ETabScrollStatus, ECustomAcl } from '@shared/enums'
import { openDownloadDialog } from 'app/utils/helpers'
import { I18NService } from '@core'
import { DashboardService } from 'app/routes/dashboard/dashboard.abstract.service'
import { IEnrolReq } from '@shared/interfaces/task'
import { ErrorCode, Currency } from '@shared/interfaces/common'
import { DetailBaseClass } from '@shared/classes/DetailBaseClass'
import { CustomACLService } from '@shared/services/acl.service'
import { IMCC, IMCCQuery, MCCType } from '@shared/components/mcc-select/mcc-select.interface'
import { MccService } from '@shared/components/mcc-select/mcc.service'
import { take, map } from 'rxjs/operators'
import { Observable, zip, forkJoin, of } from 'rxjs'

@Component({
  selector: 'app-store-detail',
  templateUrl: './detail.component.html',
})
export class StoreDetailComponent extends DetailBaseClass<Store> implements OnInit, OnDestroy {
  id: string
  store: Store
  loading = true
  token: string // used for submit
  isOpen: Boolean

  /**
   * 机构支持多币种的话，这里就为true
   * 目前一期先做成只支持单币种
   */
  isCurrencyMultiple = false

  get selectedCurrency(): Currency | Currency[] {
    const { currencies } = this.detailData.common
    if (this.isCurrencyMultiple && currencies.length) {
      return this.detailData.common.currencies[0]
    }

    return currencies
  }

  set selectedCurrency(value: Currency | Currency[]) {
    if (Array.isArray(value)) {
      this.detailData.common.currencies = value
      return
    }

    const currencies = this.detailData.common.currencies || []
    if (!currencies.length) {
      currencies.push(value)
      return
    }

    currencies[0] = value
  }

  constructor(
    public route: ActivatedRoute,
    public msg: NzMessageService,
    public pageService: PageService,
    public aclService: ACLService,
    private pageScrollService: PageScrollService,
    private storeService: StoreService,
    private dataService: DataService,
    private auditService: DashboardService,
    private i18n: I18NService,
    private customACLService: CustomACLService,
    private mccService: MccService,
    @Inject(DOCUMENT) private document: any,
  ) {
    super(pageService)
  }

  ngOnInit(): void {
    this.id = this.route.snapshot.params['id']
    this.isOpen = false
    this.initTabScroll()
    this.getData()
    this.setEditable()
  }

  ngOnDestroy() {
    this.pageService.triggerBaseEdit(false)
    this.pageService.setStoreLocked(false)
    this.pageService.setStoreNeedAudit(true)
    this.pageService.setTabScrollStatus(ETabScrollStatus.InitialLoad)
    this.pageService.setStoreBeenModified(false)
    this.dataService.resetStoreFull()
    this.customACLService.removeACLAbility(ECustomAcl.StoreEditable)
  }

  changeOpen(): void {
    this.isOpen = true
  }
  setEditable(): void {
    this.customACLService.addACLAbility(ECustomAcl.StoreEditable)
  }

  getData(): void {
    this.storeService.getOne(this.id).subscribe(full => {
      const { mcc } = full.store.common
      const params: IMCCQuery = {
        paymentBrand: MCCType.empty,
        limit: 10,
        page: 1,
        keyword: mcc,
      }
      this.mccService.getList(params).pipe(take(1)).subscribe(res => {
        full.store.common.mccEnName = res.data[0].mccEnName
        this.renderStore(full.store)
        // store the data in dataService
        this.dataService.setStoreFull(full)
        this.getToken()
        this.loading = false
      })
    })
  }

  initTabScroll(): void {
    this.pageService.tabScrollStatus$.subscribe(tabStatus => {
      this.pageScroll(ETabScrollStatus.InitialLoad)
    })
  }

  download(): void {
    // 门店下载
    const { storeNum } = this.store.common
    const params: IStoreQueryParams = {
      page: 1,
      size: 1,
      storeNum,
    }

    this.storeService.getStoreReport(params).subscribe(data => {
      const { url } = data
      openDownloadDialog(url, '门店导出')
    })
  }

  freeze(): void {
    const { intStoreCode } = this.store.common
    this.storeService.freeze(intStoreCode).subscribe(
      () => {
        this.msg.success(this.trans('GENERAL.NOTIFICATION.FREEZE_SUCCESS'))
        this.getData()
      },
      () => {
        this.msg.error(this.trans('GENERAL.NOTIFICATION.FREEZE_FAIL'))
      },
    )
  }

  unfreeze(): void {
    const { intStoreCode } = this.store.common
    this.storeService.unfreeze(intStoreCode).subscribe(
      () => {
        this.msg.success(this.trans('GENERAL.NOTIFICATION.UNFREEZE_SUCCESS'))
        this.getData()
      },
      () => {
        this.msg.error(this.trans('GENERAL.NOTIFICATION.UNFREEZE_FAIL'))
      },
    )
  }

  getToken(): void {
    const { insCode, intStoreCode } = this.store.common
    const existedToken = this.dataService.token
    if (!!existedToken) {
      this.token = existedToken
      return
    }
    const req: IEnrolReq = {
      auditType: 'store',
      insCode,
      resourceId: intStoreCode,
    }
    this.auditService.enrollment(req).subscribe(
      res => {
        const { token } = res
        if (!!token) {
          this.token = res.token
          this.dataService.setToken(this.token)
          return
        }
        /** 无需审核 */
        this.pageService.setStoreNeedAudit(false)

      },
      err => {
        const { code } = err.error
        if (code === ErrorCode.ALREADY_IN_AUDIT) {
          this.pageService.setStoreLocked(true)
          // 暂时去掉前端的提示
          // this.msg.info(this.trans('GENERAL.NOTIFICATION.ALREADY_IN_AUDIT'))
        }
      },
    )
  }

  submit(): void {
    this.storeService.submit(this.token).subscribe(
      () => {
        this.pageService.setStoreLocked(true)
        // 暂时去除提示(已在store-alinter.service提示过了)
        // this.msg.success(this.trans('GENERAL.NOTIFICATION.SUBMIT_TO_AUDIT_SUCCESS'))
      },
      err => {
        const { error } = err
        this.msg.error(this.trans('GENERAL.NOTIFICATION.SUBMIT_TO_AUDIT_FAIL'))
        console.error(error.msg)
      },
    )
  }

  save(obj: { intStoreCode: string; update: StoreUpdate }): void {}

  cancel(store: Store): void {
    this.renderStore(store)
  }

  renderStore(data: Store): void {
    this.dataService.setInsCode(data!.common!.insCode)
    this.store = data
  }

  getIsShowAction(): Observable<boolean> {
    return zip(
      this.pageService.isStoreLocked$,
      this.pageService.isStoreNeedAudit$,
      this.pageService.isStoreBeenModified$,
      this.pageService.isBaseEdit$,
      this.pageService.isTabEdit$,
    ).pipe(
      map(([isStoreLocked, isStoreNeedAudit, isStoreBeenModified, isBaseEdit, isTabEdit]): boolean => {
        /** 如果门店被锁定，那么一定不显示 */
        if (isStoreLocked) {
          return false
        }

        /** 如果不需要审核，那么也一定不显示 */
        if (!isStoreNeedAudit) {
          return false
        }

        /** 需要审核，门店已经被修改，那么一定显示 */
        if (isStoreBeenModified) {
          return true
        }

        /** 如果进入编辑,一定显示 */
        if (isBaseEdit || isTabEdit) {
          return true
        }

        /** 其他情况，不显示 */
        return false
      })
    )
  }

  private pageScroll(tabStatus: ETabScrollStatus): void {
    if (tabStatus === ETabScrollStatus.InitialLoad || tabStatus === ETabScrollStatus.Stop) {
      return
    }
    this.pageScrollService.scroll({
      document: this.document,
      scrollTarget: '.cil__scroll-div',
    })
  }

  private trans(key: string, params?: Object): string {
    return this.i18n.fanyi(key, params)
  }
}
